package com.spzx.product.lock;

import com.spzx.common.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class TestServiceImpl implements TestService {
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public synchronized Integer testLock() {
        Long skuId = 1L;
        //获取分布式锁
        String unLockValue = UUID.randomUUID().toString().replace("-", "");
        //时间限制是防止程序卡顿，无法释放锁
        //unLockValue 防止误删他人的锁
        Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("skuId" + skuId, unLockValue, 2, TimeUnit.SECONDS);
        try {
            if (lock) {
                // 查询Redis中的num值
                String value = (String) this.stringRedisTemplate.opsForValue().get("num");
                // 没有该值return
                if (StringUtils.isBlank(value)) {
                    return 0;
                }
                // 有值就转成成int
                int num = Integer.parseInt(value);
                // 把Redis中的num值+1
                this.stringRedisTemplate.opsForValue().set("num", String.valueOf(++num));

                return num;
            } else {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return testLock();
            }
        } finally {
            //释放分布式锁
//            String unLock = stringRedisTemplate.opsForValue().get("skuId" + skuId);
//            if (unLock.equals(unLockValue)) { //防止锁的误删
//                stringRedisTemplate.delete("skuId" + skuId);
//            }

            //4.2设置脚本文本
            DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
            String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                    "then\n" +
                    "    return redis.call(\"del\",KEYS[1])\n" +
                    "else\n" +
                    "    return 0\n" +
                    "end";
            redisScript.setScriptText(script);
            redisScript.setResultType(Long.class);
            stringRedisTemplate.execute(redisScript, Arrays.asList("lock:" + skuId), unLockValue);
        }
    }

//    @Override
//    public synchronized Integer testLock() {
//        // 查询Redis中的num值
//        String value = (String)this.stringRedisTemplate.opsForValue().get("num");
//        // 没有该值return
//        if (StringUtils.isBlank(value)){
//            return 0;
//        }
//        // 有值就转成成int
//        int num = Integer.parseInt(value);
//        // 把Redis中的num值+1
//        this.stringRedisTemplate.opsForValue().set("num", String.valueOf(++num));
//        return num;
//    }
}
